<template>
	<view class="online-edit-form">
		<template v-if="isReady">
			<view :style="{height: titleNavHeight + statusBarHeight + 5 + 'px'}"
				style="position: fixed;top: 0;left: 0;right: 0;z-index: 9999;background-color: #ffffff;
				border-bottom: 1px solid #ebedf0;">
				<view :style="{height: titleNavHeight + 'px', top: statusBarHeight + 'px', width: '100%'}"
					class="nav-bar"
				>
					<u-icon name="arrow-left" size="42" style="width: 40rpx;height: 40rpx;margin-right: 20rpx;"
						@click="onBack(false)"></u-icon>
					<text class="text">{{form.formName}}</text>
				</view>
			</view>
			<view :style="{height: titleNavHeight + statusBarHeight + 5 + 'px'}"></view>
			<view class="main-box">
				<scroll-view scroll-y="true" style="height: 100%">
					<u-form
						ref="form"
						:model="formData"
						:label-width="(form.labelWidth || 100) + 'px'"
						label-position="left"
						:errorType="['border-bottom', 'message']"
					>
						<online-custom-block :widgetList="form.widgetList" :key="date" />
					</u-form>
				</scroll-view>
			</view>
			<view class="menu-box flex-row-between" v-if="!formReadOnly">
				<u-button @click="onBack(false)" :custom-style="customStyle">取消</u-button>
				<u-button type="primary" @click="onSubmit()" :custom-style="customStyle1">保存</u-button>
			</view>
			<!-- 弹出子表单 -->
			<u-popup v-if="showSubPage" v-model="showSubPage" mode="left" length="100%" style="background: #F6F6F6;">
				<online-form :formId="subFormId" :rowData="editRowData" @close="onCloseSubForm" :saveData="false" />
			</u-popup>
		</template>
		<template v-else>
			<u-row style="display:flex; ;width: 100vw; height: 100vh; background: white; align-items: center; justify-content: center;">
				<u-loading mode="circle" size="50">加载中...</u-loading>
			</u-row>
		</template>
	</view>
</template>

<script>
	import { formRuleMixin } from '@/utils/validate.js';
	import {
		getBoundingClientRect
	} from "@/utils";
	import {
		OnlineFormMixins
	} from './onlineFormMixins.js';

	export default {
		name: 'onlineEditForm',
		props: {
			formConfig: {
				type: Object
			},
			// 主表数据
			masterTableData: {
				type: Object
			},
			// 需要编辑数据，如果是null则是新增
			rowData: {
				type: Object
			},
			// 是否保存到数据库
			saveData: {
				type: Boolean,
				default: true
			},
			isCopy: {
				type: Boolean,
				default: false
			}
		},
		mixins: [OnlineFormMixins, formRuleMixin],
		provide() {
			return {
				form: () => {
					return {
						...this.form,
						getDictDataList: this.getDictDataList,
						getWidgetValue: this.getWidgetValue,
						getWidgetVisible: this.getWidgetVisible,
						onValueChange: this.onValueChange,
						onWidgetValueChange: this.onWidgetValueChange,
						getDropdownParams: this.getDropdownParams,
						masterTable: this.masterTable,
						handlerOperation: this.handlerOperation,
						checkOperationVisible: this.checkOperationVisible,
						getPrimaryData: this.getPrimaryData,
						formData: this.formData,
						rules: this.rules,
						widgetImplList: this.widgetImplList
					}
				}
			}
		},
		data() {
			const {
				windowWidth,
				statusBarHeight
			} = uni.getSystemInfoSync()
			const rect = getBoundingClientRect(windowWidth, statusBarHeight);
			return {
				isUpdateFrom: 0,
				isReady: false,
				windowWidth: windowWidth,
				statusBarHeight: statusBarHeight,
				titleNavHeight: (rect.top - statusBarHeight) * 2 + rect.height,
				emptyWidth: rect.left - 10,
				date: (new Date()).valueOf(),
				customStyle: {
					borderRadius: '0',
					border: '1px solid #ebedf0'
				},
				customStyle1: {
					borderRadius: '0',
				}
			}
		},
		methods: {
			onBack(refresh, data) {
				refresh = refresh || false;
				this.$emit('close', refresh, data);
			},
			onSaveFormData() {
				let that = this
				if (this.masterTable == null || this.masterTable.datasource == null) {
					uni.showToast({
						icon: 'error',
						title: '表单使用主数据源或主表不存在！'
					})
					return;

				}
				let params = {
					datasourceId: this.masterTable.datasource.datasourceId,
					relationId: (this.masterTable.relation || {}).relationId,
					masterData: this.isRelation ? undefined : this.formData[this.masterTable.datasource.variableName]
				}
				if (this.isRelation) {
					// 从表数据添加或更新
					params.slaveData = {
						...this.formData[this.masterTable.relation.variableName]
					}
					// 设置关联字段的值
					let slaveColumnValue = (this.masterTableData || {})[this.masterTable.relation.masterColumn.columnName];
					if (slaveColumnValue != null) {
						params.slaveData[this.masterTable.relation.slaveColumn.columnName] = slaveColumnValue;
					}
				} else {
			
					// 设置一对多从表数据
					params.slaveData = this.tableWidgetList.reduce((retObj, widget) => {
						if (widget.relation != null) {
							retObj[widget.relation.variableName] = that.formData[widget.relation.variableName];
						}
						return retObj;
					}, {});
				}

				// 把slaveData里的relationVariableName替换成relationId
				if (!this.isRelation && params.slaveData) {
					let slaveDataKeyList = Object.keys(params.slaveData);
					if (slaveDataKeyList.length > 0) {
						let relationVariableNameMap = new Map();
						this.form.tableMap.forEach(table => {
							if (table.relation != null) {
								relationVariableNameMap.set(table.relation.variableName, table.relation
									.relationId);
							}
						});
						slaveDataKeyList.forEach(key => {
							let relationId = relationVariableNameMap.get(key);
							if (relationId != null) {
								params.slaveData[relationId] = params.slaveData[key];
							}
							params.slaveData[key] = undefined;
						});
					}
				}
				let commitUrl;
				if (this.isRelation) {
					// 从表提交数据
					commitUrl = (this.rowData == null || this.isCopy) ?
						'/admin/online/onlineOperation/addOneToManyRelation/' :
						'/admin/online/onlineOperation/updateOneToManyRelation/';
				} else {
					// 主表提交数据
					commitUrl = (this.rowData == null || this.isCopy) ? '/admin/online/onlineOperation/addDatasource/' :
						'/admin/online/onlineOperation/updateDatasource/';
				}
				commitUrl += this.masterTable.datasource.variableName;
				this.doUrl(commitUrl, 'post', params).then(res => {
					uni.showToast({
						icon: 'success',
						title: '保存成功！'
					})
					this.onBack(true);
				}).catch(e => {});
			},
			onSubmit() {
				if (Array.isArray(this.richEditWidgetList)) {
					this.richEditWidgetList.forEach(richWidget => {
						if (richWidget && richWidget.widgetImpl) {
							this.onValueChange(richWidget, richWidget.widgetImpl.getHtml());
						}
					});
				}
				this.$refs.form.validate(async valid => {
					if (!valid) return;
					if (this.saveData) {
						// 非级联保存数据
						this.onSaveFormData();
					} else {
						// 级联添加返回表单数据到父表单
						let data = null;
						if (this.isRelation) {
							data = this.formData[this.masterTable.relation.variableName];
						}
						if (this.form.eventInfo && typeof this.form.eventInfo[this.OnlineFormEventType.BEFORE_COMMIT_FORM_DATA] === 'function') {
							data = await this.form.eventInfo[this.OnlineFormEventType.BEFORE_COMMIT_FORM_DATA](data);
						}
						this.onBack(true, data);
					}
				});
				//validateForm
			},
			onCloseSubForm(refresh, data) {
				if (refresh && this.operationCallback) {
					this.operationCallback(data);
				}
				this.showSubPage = false;
				if (refresh) this.onRefresh();
			},
			getTableData(widget) {
				return widget.relation ? this.formData[widget.relation.variableName] : [];
			},
			setTableData(widget, dataList) {
				if (widget == null) return;
				if (widget.relation) {
					this.formData[widget.relation.variableName] = dataList;
				}
			},
			async loadRelationTableData(widget) {
				try {
					if (widget == null || widget.datasource == null || widget.relation == null) {
						throw new Error('未配置关联表');
					}
					if (!widget.relation.slaveColumn && widget.relation.slaveColumnId) {
						widget.relation.slaveColumn = this.formConfig.relationMap.get(widget.relation.relationId).slaveColumn;
					}

					let params = {
						datasourceId: widget.datasource.datasourceId,
						relationId: widget.relation.relationId,
						filterDtoList: [{
							tableName: widget.table.tableName,
							columnName: widget.relation.slaveColumn.columnName,
							filterType: this.SysOnlineColumnFilterType.EQUAL_FILTER,
							columnValue: (this.formData[widget.datasource.variableName] || {})[widget
								.relation.masterColumn.columnName]
						}]
					}
					// 脱敏设置
					params.ignoreMaskFields = this.getIgnoreMaskFields(widget);
					if (widget.eventInfo && typeof widget.eventInfo[this.OnlineFormEventType.BEFORE_LOAD_TABLE_DATA] === 'function') {
						params = await widget.eventInfo[this.OnlineFormEventType.BEFORE_LOAD_TABLE_DATA](params);
					}
					if (params == null) throw new Error('取消加载数据');
					let res = await this.doUrl(
						`/admin/online/onlineOperation/listByOneToManyRelationId/${widget.datasource.variableName}`,
						'post',
						params
					);

					if (widget.eventInfo && typeof widget.eventInfo[this.OnlineFormEventType.AFTER_LOAD_TABLE_DATA] ===
							'function') {
							res.dataList = await widget.eventInfo[this.OnlineFormEventType
								.AFTER_LOAD_TABLE_DATA](res.dataList);
						}
						// 复制数据，清空主键id以及自动编码字段
						if (this.isCopy) {
							let temp = new Date().getTime();
							let autoCodeColumnName = [];
							if (widget.table && Array.isArray(widget.table.columnList)) {
								widget.table.columnList.forEach(column => {
									if (column.fieldKind === this.SysOnlineFieldKind.AUTO_CODE) {
										autoCodeColumnName.push(column.columnName);
									}
								});
							}
							res.dataList.forEach(item => {
								if (widget.primaryColumnName) item[widget.primaryColumnName] =
									undefined;
								item.__cascade_add_id__ = temp++;
								autoCodeColumnName.forEach(columnName => {
									item[columnName] = undefined;
								});
							});
						}
						this.formData[widget.relation.variableName] = res.dataList;
				} catch (e) {
					console.error(e);
					throw e;
				}
			},
			clearFormData(data, columnList) {
				if (data == null || !Array.isArray(columnList)) return;
				columnList.forEach(columnName => {
					data[columnName] = undefined;
				});
			},
			initFormData() {
				if (this.rowData != null) {
					return new Promise((resolve, reject) => {
						// 如果是复制，清空主键以及自动编码字段
						let clearColumnList = [];
						if (this.isCopy && this.masterTable && Array.isArray(this.masterTable.columnList)) {
							this.masterTable.columnList.forEach(column => {
								if (column.primaryKey || column.fieldKind === this.SysOnlineFieldKind
									.AUTO_CODE) {
									clearColumnList.push(column.columnName);
								}
							});
						}
						if (this.isRelation) {
							this.formData[this.masterTable.relation.variableName] = {
								...this.rowData
							}
							this.clearFormData(this.formData[this.masterTable.relation.variableName],
								clearColumnList);
							resolve();
						} else {
							// 初始化主表以及一对一字段数据
							let relationNameList = [];
							let datasourceName;
							this.form.tableMap.forEach(table => {
								if (table.relation && table.relation.relationType === this
									.SysOnlineRelationType.ONE_TO_ONE) {
									relationNameList.push(table.relation.variableName);
								} else if (table.relation == null) {
									datasourceName = table.datasource.variableName;
								}
							});
							Object.keys(this.rowData).forEach(key => {
								if (relationNameList.indexOf(key) === -1) {
									// 主表字段
									this.formData[datasourceName][key] = this.rowData[key];
								} else {
									// 从表字段
									if (this.rowData[key]) this.formData[key] = this.rowData[key];
								}
							});
							// 初始化一对多数据
							if (Array.isArray(this.tableWidgetList) && this.tableWidgetList.length > 0) {
								try {
									let httpCallList = this.tableWidgetList.map(widget => {
										if (widget.relation && widget.relation.relationType === this
											.SysOnlineRelationType.ONE_TO_MANY) {
											return this.loadRelationTableData(widget);
										}
										return null;
									}).filter(item => item != null);
									Promise.all(httpCallList).then(res => {
										this.clearFormData(this.formData[datasourceName], clearColumnList);
										resolve();
									}).catch(e => {
										this.clearFormData(this.formData[datasourceName], clearColumnList);
										reject(e);
									});
								} catch (e) {}
							} else {
								this.clearFormData(this.formData[datasourceName], clearColumnList);
								resolve();
							}
						}
					});
				} else {
					return Promise.resolve();
				}
			}
		},
		computed: {
			form() {
				this.isUpdateFrom++
				return this.buildFormConfig(this.formConfig);
			}
		},
		watch: {
			isUpdateFrom: {
				handler() {
					let _this = this
					this.isReady = false;
					this.initPage(this.form);
					this.initFormWidgetList(this.form);
					this.initWidgetRule(this.form);
					if (this.form.eventInfo && typeof this.form.eventInfo[this.OnlineFormEventType.AFTER_CREATE_FORM] === 'function') {
						this.form.eventInfo[this.OnlineFormEventType.AFTER_CREATE_FORM]();
					}
					this.initFormData().then(() => {
						if (_this.form.eventInfo && typeof _this.form.eventInfo[_this.OnlineFormEventType.AFTER_LOAD_FORM_DATA] ===
							'function') {
							_this.form.eventInfo[_this.OnlineFormEventType.AFTER_LOAD_FORM_DATA]();
						}
						_this.initWidgetLinkage();
					}).catch(e => {

					}).finally(res => {
						_this.isReady = true;
					});
				},
				immediate: true
			}
		}
	}
</script>

<style lang="less">
	.online-edit-form {
		height: 100vh;
		display: flex;
		flex-direction: column;
		background-color: #F6F7F9;

		.nav-bar {
			position: absolute;
			display: flex;
			flex-direction: row;
			align-items: center;
			padding-left: 20rpx;

			.text {
				width: calc(100vw - 80px);
				color: #323233;
				font-weight: 500;
				font-size: 30rpx;
				display: flex;
				justify-content: center;
				justify-items: center;
			}
		}

		.main-box {
			flex: 1;
			overflow: auto;
		}

		.menu-box {
			flex-grow: 0;
			flex-shrink: 0;
			width: 100%;
			padding: 20rpx 30rpx;
			flex-wrap: nowrap;
			background: white;
			box-sizing: border-box;
			margin-top: 30rpx;

			button::after {
				border-radius: 0;
				border: none;
			}

			&>u-button,
			&>.u-btn {
				&:first-child {
					width: 24%;
				}

				&:last-child {
					width: 74%;
				}
			}
		}
	}
</style>